home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dobj / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-09  |  9.5 KB  |  491 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  *  MAIN.C
  9.  *
  10.  *  DISOBJ [-nc] [-pc<startpc>] [-do<dataorg>] objectfile(s)
  11.  *
  12.  *  Utility to disassemble an object module
  13.  */
  14.  
  15. #include "defs.h"
  16.  
  17. #ifdef AMIGA
  18. #include <lib/version.h>
  19. #else
  20. #include <include/lib/version.h>
  21. #endif
  22.  
  23. Prototype short DDebug;
  24. Prototype short OutAsm;
  25. Prototype short NoCode;
  26. Prototype short NoData;
  27. Prototype short NumHunks;
  28. Prototype int  StartPc;
  29. Prototype int  StartDo;
  30. Prototype ProgramUnit *PUAry[MAXUNITS];
  31.  
  32. void help(void);
  33. long ScanObjectFile(FILE *fi, long endPos);
  34. void UnAssembleObjectFile(FILE *fi);
  35. void ResetHashTables(void);
  36.  
  37. IDENT("DOBJ",".3");
  38. DCOPYRIGHT;
  39.  
  40. short DDebug;
  41. short OutAsm;
  42. short NumHunks;
  43. short NoCode;
  44. short NoData;
  45. ProgramUnit *PUAry[MAXUNITS];
  46.  
  47. int  StartPc = 0;
  48. int  StartDo = 0;
  49.  
  50. int
  51. main(int ac, char **av)
  52. {
  53.     short i;
  54.  
  55.     rel_init();
  56.     sym_init();
  57.  
  58.     if (ac == 1)
  59.     help();
  60.  
  61.     for (i = 1; i < ac; ++i) {
  62.     char *ptr = av[i];
  63.  
  64.     if (*ptr == '-') {
  65.         ptr += 2;
  66.  
  67.         switch(ptr[-1]) {
  68.         case 'n':
  69.         switch(*ptr) {
  70.         case 'd':
  71.             NoData = 1;
  72.             break;
  73.         case 'c':
  74.             NoCode = 1;
  75.             break;
  76.         default:
  77.             help();
  78.         }
  79.         break;
  80.         case 'a':
  81.         OutAsm = 1;
  82.         break;
  83.         case 'd':
  84.         if (*ptr == 'o') {
  85.             StartDo = strtol(ptr + 1, NULL, 0);
  86.         } else {
  87.             if (*ptr)
  88.             DDebug = atoi(ptr);
  89.             else
  90.             DDebug = 1;
  91.         }
  92.         break;
  93.         case 'o':
  94.         if (*ptr == 0)
  95.             ptr = av[++i];
  96.  
  97.         freopen(ptr, "w", stdout);
  98.         *ptr = 0;
  99.         break;
  100.         case 'p':
  101.         if (*ptr == 'c') {
  102.             StartPc = strtol(ptr + 1, NULL, 0);
  103.         } else {
  104.             help();
  105.         }
  106.         break;
  107.         default:
  108.         help();
  109.         break;
  110.         }
  111.     }
  112.     }
  113.  
  114.     InitCodeList();
  115.  
  116.     for (i = 1; i < ac; ++i) {
  117.     char *ptr = av[i];
  118.     FILE *fi;
  119.  
  120.     if (*ptr == '-')
  121.         continue;
  122.     if (*ptr == 0)
  123.         continue;
  124.  
  125.     if ((fi = fopen(ptr, "r")) != NULL) {
  126.         long endPos;
  127.         long pos = 0;
  128.  
  129.         fseek(fi, 0L, 2);
  130.         endPos = ftell(fi);
  131.  
  132.         do {
  133.         fseek(fi, pos, 0);
  134.         ResetHashTables();
  135.         pos = ScanObjectFile(fi, endPos);
  136.         UnAssembleObjectFile(fi);
  137.         } while (pos < endPos);
  138.  
  139.         fclose(fi);
  140.     } else {
  141.         cerror(EERROR, "Unable to open %s", ptr);
  142.     }
  143.     }
  144.     return(0);
  145. }
  146.  
  147. void
  148. help(void)
  149. {
  150.     printf("%s\n%s\n", Ident, DCopyright);
  151.     puts("DISOBJ objfile(s) [-o outfile] [-d[#]]");
  152.     exit(1);
  153. }
  154.  
  155. /*
  156.  *  Disassemble a module
  157.  */
  158.  
  159. long
  160. ScanObjectFile(FILE *fi, long endPos)
  161. {
  162.     long unitData[2];
  163.     short thisHunk = 0;
  164.  
  165.     while (freadl(unitData, 4, 1, fi) == 1) {
  166.     ProgramUnit *unit;
  167.  
  168.     if (thisHunk == 0) {
  169.         int bytes;
  170.  
  171.         switch(unitData[0]) {
  172.         case 0x3E7:
  173.         if (freadl(&bytes, 4, 1, fi) != 1)
  174.             cerror(EFATAL, "unexpected EOF");
  175.         bytes = bytes * 4;
  176.         printf("HUNK_UNIT ");
  177.         while (bytes) {
  178.             short c;
  179.             if ((c = getc(fi)) != 0)
  180.             putc(c, stdout);
  181.             --bytes;
  182.         }
  183.         puts("");
  184.         break;
  185.         case 0x3F3:     /*    hunk_header (executable)    */
  186.         printf("HUNK_HEADER ");
  187.         while (freadl(&bytes, 4, 1, fi) == 1 && bytes) {
  188.             bytes = bytes * 4;
  189.             printf("(");
  190.             while (bytes) {
  191.             short c;
  192.             if ((c = getc(fi)) != 0)
  193.                 putc(c, stdout);
  194.             --bytes;
  195.             }
  196.             printf(")");
  197.         }
  198.         if (freadl(&bytes, 4, 1, fi) == 1) {     /*  table size  */
  199.             int begNo;
  200.             int endNo;
  201.  
  202.             printf(" tableSize=%d\n", bytes);
  203.  
  204.             freadl(&begNo, 4, 1, fi);
  205.             freadl(&endNo, 4, 1, fi);
  206.             while (begNo <= endNo ) {
  207.             long value;
  208.             freadl(&value, 4, 1, fi);
  209.             printf("    hunk #%d  %ld bytes\n", begNo, value * 4);
  210.             ++begNo;
  211.             }
  212.         }
  213.         break;
  214.         default:
  215.         cerror(EFATAL, "Expected HUNK_UNIT (0x3E7), got %08x", unitData[0]);
  216.         break;
  217.         }
  218.         freadl(unitData, 4, 1, fi);
  219.     } else {
  220.         if (unitData[0] == 0x3E7) {     /*  library */
  221.         fseek(fi, -4L, 1);
  222.         break;
  223.         }
  224.     }
  225.  
  226.     unit = malloc(sizeof(ProgramUnit));
  227.     clrmem(unit, sizeof(*unit));
  228.     if (unit == NULL)
  229.         cerror(EFATAL, "malloc failed");
  230.  
  231.     PUAry[thisHunk] = unit;
  232.  
  233.     /*
  234.      *  Scan rest of hunk
  235.      */
  236.  
  237.     while (unitData[0] != 0x3F2) {
  238.         if (DDebug)
  239.         fprintf(stderr, "scan hunk %02x %08lx\n", thisHunk, unitData[0]);
  240.  
  241.         switch((uword)unitData[0]) {
  242.         case 0x3E8:     /*    hunk_Name   */
  243.         {
  244.             long bytes;
  245.             if (freadl(&bytes, 4, 1, fi) != 1)
  246.             cerror(EFATAL, "unexpected EOF");
  247.             bytes = bytes * 4;
  248.             if ((unit->pu_Name = malloc(bytes + 1)) == NULL)
  249.             cerror(EFATAL, "malloc failed");
  250.             clrmem(unit->pu_Name, bytes + 1);
  251.             fread(unit->pu_Name, bytes, 1, fi);
  252.         }
  253.         break;
  254.         case 0x3E9:
  255.         case 0x3EA:
  256.         case 0x3EB:
  257.         {
  258.             long bytes;
  259.  
  260.             unit->pu_Type = unitData[0];
  261.             if (freadl(&bytes, 4, 1, fi) != 1)
  262.             cerror(EFATAL, "Unexpected EOF");
  263.             unit->pu_Size = bytes * 4;
  264.             if ((uword)unitData[0] != 0x3EB) {
  265.             unit->pu_Offset = ftell(fi);
  266.             fseek(fi, unit->pu_Size, 1);    /*  skip contents   */
  267.             }
  268.         }
  269.         break;
  270.         case 0x3EC:     /*    hunk_reloc32    */
  271.         case 0x3ED:     /*    hunk_reloc16    */
  272.         case 0x3EE:     /*    hunk_reloc8    */
  273.         case 0x3F8:     /*    hunk_reloc16D    */
  274.         {
  275.             short size = 4;
  276.             short flags= 0;
  277.             long numOffsets;
  278.             long hunkNo;
  279.             long offset;
  280.  
  281.             switch((uword)unitData[0]) {
  282.             case 0x3ED:
  283.             size = 2;
  284.             flags |= RF_PCREL;
  285.             break;
  286.             case 0x3F8:
  287.             size = 2;
  288.             flags |= RF_A4REL;
  289.             break;
  290.             case 0x3EE:
  291.             size = 1;
  292.             flags |= RF_PCREL;
  293.             break;
  294.             }
  295.             while (freadl(&numOffsets, 4, 1, fi) == 1 && numOffsets) {
  296.             if (freadl(&hunkNo, 4, 1, fi) == 1) {
  297.                 while (numOffsets) {
  298.                 if (freadl(&offset, 4, 1, fi) != 1)
  299.                     break;
  300.                 AddRelocInfo(thisHunk, hunkNo, size, flags, offset, NULL);
  301.                 --numOffsets;
  302.                 }
  303.             }
  304.             }
  305.         }
  306.         break;
  307.         case 0x3EF:     /*    hunk_ext    */
  308.         case 0x3F0:     /*    hunk_sym    */
  309.         {
  310.             ulong symHdr;
  311.  
  312.             while (freadl(&symHdr, 4, 1, fi) == 1 && symHdr) {
  313.             long bytes = (symHdr & 0x00FFFFFF) * 4;
  314.             long numRefs;
  315.             short size;
  316.             short flags;
  317.             Symbol *sym;
  318.  
  319.             if ((sym = malloc(sizeof(Symbol) + bytes + 1)) == NULL)
  320.                 cerror(EFATAL, "No Memory");
  321.  
  322.             clrmem(sym, sizeof(Symbol) + 1 + bytes);
  323.             sym->sm_Type = symHdr >> 24;
  324.             fread(sym->sm_Name, bytes, 1, fi);
  325.             if (sym->sm_Type <= 3)
  326.                 freadl(&sym->sm_Value, 4, 1, fi);
  327.             sym->sm_DefHunk = thisHunk;
  328.  
  329.             sym = AddSymbol(sym);
  330.  
  331.             size = 4;
  332.             flags = 0;
  333.  
  334.             switch(sym->sm_Type) {
  335.             case 0:     /*    symb    */
  336.             case 1:     /*    def    */
  337.             case 2:     /*    abs    */
  338.             case 3:     /*    ref    */
  339.                 break;
  340.             case 130:   /*    refcomm */
  341.                 freadl(&sym->sm_CommonSize, 4, 1, fi);
  342.                 size = sym->sm_CommonSize;
  343.                 break;
  344.             case 129:   /*    ref32    */
  345.             case 131:   /*    ref16    */
  346.                 if (sym->sm_Type == 131) {
  347.                 size = 2;
  348.                 flags |= RF_PCREL;
  349.                 }
  350.             case 132:   /*    ref8    */
  351.                 if (sym->sm_Type == 132) {
  352.                 size = 1;
  353.                 flags |= RF_PCREL;
  354.                 }
  355.             case 134:   /*    ref 16D */
  356.                 if (sym->sm_Type == 134) {
  357.                 size = 2;
  358.                 flags |= RF_A4REL;
  359.                 }
  360.  
  361.                 if (freadl(&numRefs, 4, 1, fi) != 1)
  362.                 cerror(EFATAL, "Unexpected EOF");
  363.                 while (numRefs) {
  364.                 long offset;
  365.                 freadl(&offset, 4, 1, fi);
  366.                 AddRelocInfo(thisHunk, -1, size, flags, offset, sym);
  367.                 --numRefs;
  368.                 }
  369.             }
  370.             }
  371.         }
  372.         break;
  373.         case 0x3F1: /*  hunk_debug    */
  374.         {
  375.             long bytes;
  376.             if (freadl(&bytes, 4, 1, fi) == 1) {
  377.             bytes = bytes * 4;
  378.             fseek(fi, bytes, 1);    /*  skip it */
  379.             }
  380.         }
  381.         break;
  382.         default:
  383.         cerror(EFATAL, "Unknown hunk type 0x%08lx offset 0x%lx", unitData[0], ftell(fi));
  384.         break;
  385.         }
  386.         if (freadl(unitData, 4, 1, fi) != 1)
  387.         cerror(EFATAL, "Unexpected EOF");
  388.     }
  389.     ++thisHunk;
  390.     if (thisHunk == MAXUNITS)
  391.         cerror(EFATAL, "Can only support %d UNITs in obj file!", MAXUNITS);
  392.     }
  393.     NumHunks = thisHunk;
  394.     return(ftell(fi));
  395. }
  396.  
  397. void
  398. UnAssembleObjectFile(FILE *fi)
  399. {
  400.     short srcHunk;
  401.  
  402.     for (srcHunk = 0; srcHunk < NumHunks; ++srcHunk) {
  403.     ProgramUnit *su = PUAry[srcHunk];
  404.  
  405.     puts("");
  406.     switch((uword)su->pu_Type) {
  407.     case 0x3E9:
  408.         printf("HUNK_CODE");
  409.         fseek(fi, su->pu_Offset, 0);
  410.         break;
  411.     case 0x3EA:
  412.         printf("HUNK_DATA");
  413.         fseek(fi, su->pu_Offset, 0);
  414.         break;
  415.     case 0x3EB:
  416.         printf("HUNK_BSS ");
  417.         break;
  418.     }
  419.     printf(" #%02d (%-15s) Hunk=%08lx Size=%d bytes\n",
  420.         srcHunk,
  421.         ((su->pu_Name) ? su->pu_Name : ""),
  422.         (long)su->pu_Type,
  423.         su->pu_Size
  424.     );
  425.  
  426.     {
  427.         int offset = 0;
  428.         Symbol *sym;
  429.         Symbol *symNext;
  430.  
  431.         for (sym = FindSymbolOffset(offset, srcHunk); sym; sym = symNext) {
  432.         symNext = FindSymbolNext(sym);
  433.  
  434.         if (sym->sm_Type > 1) {
  435.             printf(" %02x.%08lx %-20s TYPE %d\n", srcHunk, (long)sym->sm_Value, sym->sm_Name, sym->sm_Type);
  436.             continue;
  437.         }
  438.         if (sym->sm_Value != offset) {
  439.             if (sym->sm_Value < offset)
  440.             cerror(EFATAL, "Soft Error, Symbol/sort");
  441.  
  442.             switch((uword)su->pu_Type) {
  443.             case 0x3E9:
  444.             if (NoCode == 0)
  445.                 DumpCode(fi, srcHunk, offset, sym->sm_Value);
  446.             break;
  447.             case 0x3EA:
  448.             if (NoData == 0)
  449.                 DumpData(fi, srcHunk, offset, sym->sm_Value);
  450.             break;
  451.             }
  452.             offset = sym->sm_Value;
  453.         }
  454.         if ((uword)su->pu_Type == 0x3E9) {
  455.             if (NoCode == 0)
  456.             puts("");
  457.             printf("*%02x.%08lx %s:\t(%d bytes)\n",
  458.             srcHunk,
  459.             (long)offset,
  460.             sym->sm_Name,
  461.             symNext ? symNext->sm_Value - offset : su->pu_Size - offset
  462.             );
  463.         } else {
  464.             printf(" %02x.%08lx %s:\n", srcHunk, (long)offset, sym->sm_Name);
  465.         }
  466.         }
  467.  
  468.         if (offset != su->pu_Size) {
  469.         switch((uword)su->pu_Type) {
  470.         case 0x3E9:
  471.             if (NoCode == 0)
  472.             DumpCode(fi, srcHunk, offset, su->pu_Size);
  473.             break;
  474.         case 0x3EA:
  475.             if (NoData == 0)
  476.             DumpData(fi, srcHunk, offset, su->pu_Size);
  477.             break;
  478.         }
  479.         }
  480.     }
  481.     }
  482. }
  483.  
  484. void
  485. ResetHashTables(void)
  486. {
  487.     ResetReloc();
  488.     ResetSymbol();
  489. }
  490.  
  491.